iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0

從今天開始要進入 Part 3 啦!Part 3 主要是 functional programming 下更高層的抽象,也就是說把之前各種主題下常看到的模式概念整合起來、抽象出來成 library,節省重複的程式碼設計,之後的幾天目標就是介紹這些抽象概念,訓練你辨識模式,然後介紹一下各種模式的優點。

Monoid 是我們將要介紹的第一個純粹的代數資料結構,僅由代數性質定義。

什麼是 Monoid?

Monoid 來自於數學,在 Category Theory 中,它意思為一個 category 只有一個 object,數學上的定義在這裡不太重要(詳細的說明可以看 維基百科)。

首先我們來看一下連續字串的代數性質,foo + bar 會等於 foobar,而空字串 "" 在這裡面被稱為 identity element (單位元素),如果我們用 (s + "")("" + s),其結果都會是 s,

進一步來看,如果我們合併 3 個字串 (r + s + t),其算子是具有 Associative property (結合律) 性質的,也就是說不管我們怎麼用括號分隔,((r + s) + t)(r + (s + t)),其結果都相同,

相同的定律對數字也適用,例如 (x + y) + z 始終會等於 x + (y + z),它的單位元素是 0,

&&|| 同樣也具有結合律;

這種型態的代數性就稱為 Monoid,而 Monoid 定律會由下列項目組成:

  • 某個型態 A。
  • 有一個具有結合律的 function combine,它接受 2 個型態為 A 的參數,然後合併它們做為結果,combine(combine(x, y), z) == combine(x, combine(y, z)) ,其 x, y, z 的型態皆為 A。
  • 有一個稱為 empty 的值,它是單位元素並能滿足以下操作,combine(x, empty) == xcombine(empty, x) == x,x 的型態為 A。

把這些用 Scala 表示的話程式長這樣,

trait Monoid[A]:
  def combine(a1: A, a2: A): A
  def empty: A

用字串來實作的話長這樣。

  val stringMonoid: Monoid[String] = new:
    def combine(a1: String, a2: String) = a1 + a2
    val empty = ""

無參數的 function 可以在實作時用 val 實作。


Exercise D22-1

來實作加、乘、AND 和 OR 操作吧!

val intAddition: Monoid[Int]
val intMultiplication: Monoid[Int]
val booleanAnd: Monoid[Boolean]
val booleanOr: Monoid[Boolean]

Exercise D22-2

用 Option 來實作 Monoid 介面。

def optionMonoid[A]: Monoid[Option[A]]

Monoid 就是能用一個相同型態二元操作 function 滿足結合律且有著單位元素的東西啦!


Day 22 - Exercise answer


上一篇
能自由組合的解析器 Library (3)
下一篇
Monoids (2)
系列文
用 Scala 3 寫的 Functional Programming 會長什麼樣子?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言